#include "WelfarePart.h"
#include "Player.h"
#include "PlayerMgr.h"
#include "Common/TableData/WelfareSignCfg.h"
#include "Common/Utility/TimeUtility.h"
#include "drop/DropMgr.h"

using namespace ProtoBuf;

WelfarePart::WelfarePart()
{
	mSignRecord = 0;
	mSignReward = 0;
	//mSignRewardCount = 1;
	mSignRefreshTime = 0;
}

WelfarePart::~WelfarePart()
{
}

bool WelfarePart::SaveDB(CharacterDBInfo& characterDB)
{
	CharacterDBWelfareInfo* pWelfareInfo = characterDB.mutable_welfaredata();
	if (nullptr != pWelfareInfo)
	{
		CharacterDBSignInfo* pSignInfo = pWelfareInfo->mutable_signinfo();
		if (nullptr != pSignInfo)
		{
			pSignInfo->set_signrecord(mSignRecord);
			pSignInfo->set_signreward(mSignReward);
			//pSignInfo->set_signrewardcount(mSignRewardCount);
			pSignInfo->set_signrefreshtime(mSignRefreshTime);
		}
	}

	return true;
}

bool WelfarePart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB /* = nullptr */)
{
	Part::Init(pMaster, partType);

	const CharacterDBWelfareInfo& welfareInfo = pCharacterDB->welfaredata();
	const CharacterDBSignInfo& signInfo = welfareInfo.signinfo();
	mSignRecord = signInfo.signrecord();
	mSignReward = signInfo.signreward();
	//mSignRewardCount = (signInfo.signrewardcount() == 0 ? 1 : signInfo.signrewardcount());
	mSignRefreshTime = signInfo.signrefreshtime();

	uint32_t nowTime = Time::Now().UnixSec();
	if (TimeUtility::CheckWeekUpdate(nowTime, mSignRefreshTime))
	{
		mSignRecord = 0;
		mSignReward = 0;
	}
	
	return true;
}

bool WelfarePart::UnInit()
{
	return true;
}

bool WelfarePart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	switch (cmd)
	{
	case CLIENT_TO_LOGIC_ONSIGN:
	{
		HandleOnSignReq(data, len);
		break;
	}
	case CLIENT_TO_LOGIC_SIGNINFO:
	{
		HandleSignInfo(data, len);
		break;
	}
	default:
		break;
	}
	return true;
}

bool WelfarePart::HandleOnSignReq(const char* data, uint32_t len)
{
	ProtoBuf::CGOnSignReq onSignReq;
	ProtoBuf::GCOnSignRsp onSignRsp;

	if (!onSignReq.ParseFromArray(data, len))
	{
		MMOLOG_FMT_ERROR("[logic] WelfarePart::HandleOnSignReq CGOnSignReq parse failed...");
		return false;
	}

	Date nowTime = Time::GetLocalDate();
	uint32_t oldSignRecord = mSignRecord;
	oldSignRecord |= 1 << nowTime.wday;
	if(oldSignRecord == mSignRecord)
	{
		onSignRsp.set_ret(RET_WELFARE_HAVE_ONSIGN);
		m_pMaster->SendDataToClientEx(EMODULE_ID_WELFARE, LOGIC_TO_CLIENT_ONSIGN, &onSignRsp);
		return false;
	}
	uint32_t rewardCount = g_GetLogicService()->GetWeekCountFromOpen();
	const WelfareSignCfgInfo* pWelfareSignCfgInfo = g_GetWelfareSignCfgTable()->GetWelfareSignCfgInfo(rewardCount);
	if (nullptr == pWelfareSignCfgInfo)
	{
		//如果为空了 那么从1重新开始循环
		rewardCount = 1;
		pWelfareSignCfgInfo = g_GetWelfareSignCfgTable()->GetWelfareSignCfgInfo(rewardCount);
		if (nullptr == pWelfareSignCfgInfo)
		{
			onSignRsp.set_ret(RET_FAIL);
			m_pMaster->SendDataToClientEx(EMODULE_ID_WELFARE, LOGIC_TO_CLIENT_ONSIGN, &onSignRsp);
			return false;
		}
	}

	//给奖励了
	if (nullptr != pWelfareSignCfgInfo)
	{
		//如果是周日的话 给最后一个奖励
		uint32_t nBoxID = 0;
		if (nowTime.wday == 0)
		{
			const WelfareSignRewardCfgInfo& signRewardCfg = pWelfareSignCfgInfo->vecWelfareSignRewardCfg.back();
			nBoxID = signRewardCfg.Id;
		}
		else
		{
			const WelfareSignRewardCfgInfo& signRewardCfg = pWelfareSignCfgInfo->vecWelfareSignRewardCfg.at(nowTime.wday - 1);
			nBoxID = signRewardCfg.Id;
		}
		VEC_INT32 vecBox;
		vecBox.clear();
		vecBox.push_back(nBoxID);
		SItemSourceParam sourceParam;
		sourceParam.source = S_SIGN_IN;
		int32_t ret = g_GetDropMgr()->PlayerAddBox(dynamic_cast<Player*>(m_pMaster), vecBox, sourceParam);
		if (RET_SUCCESS != ret)
		{
			onSignRsp.set_ret(ret);
			m_pMaster->SendDataToClientEx(EMODULE_ID_WELFARE, LOGIC_TO_CLIENT_ONSIGN, &onSignRsp);
			return false;
		}
		//设置领取奖励标记
		mSignReward |= 1 << nowTime.wday;
		mSignRecord |= 1 << nowTime.wday;

		//如果是周日 那么周期次数+1
		if (nowTime.wday == 0)
		{
			//mSignRewardCount++;
		}

		mSignRefreshTime = (uint32_t)Time::Now().UnixSec();
		onSignRsp.set_ret(RET_SUCCESS);
		m_pMaster->SendDataToClientEx(EMODULE_ID_WELFARE, LOGIC_TO_CLIENT_ONSIGN, &onSignRsp);
		return true;
	}

	return false;
}

bool WelfarePart::HandleSignInfo(const char* data, uint32_t len)
{
	ProtoBuf::CGQuerySignInfoReq signInfoReq;

	if (!signInfoReq.ParseFromArray(data, len))
	{
		MMOLOG_FMT_ERROR("[logic] WelfarePart::HandleSignInfo CGQuerySignInfoReq parse failed...");
		return false;
	}

	SendSignInfo();
	return true;
}

void WelfarePart::SendSignInfo()
{
	ProtoBuf::GCQuerySignInfoRsp signInfoRsp;
	signInfoRsp.set_ret(RET_SUCCESS);
	signInfoRsp.set_signreward(mSignReward);
	signInfoRsp.set_signrewardcount(g_GetLogicService()->GetWeekCountFromOpen());
	signInfoRsp.set_signrecord(mSignRecord);
	m_pMaster->SendDataToClientEx(EMODULE_ID_WELFARE, LOGIC_TO_CLIENT_SIGNINFO, &signInfoRsp);
}

bool WelfarePart::WeekUpdate(uint64_t unixSec)
{
	RefreshSignInfo();

	return true;
}

void WelfarePart::RefreshSignInfo()
{
	mSignReward = 0;
	mSignRecord = 0;

	SendSignInfo();
}